#define DEBUG
#pragma GCC optimize("-Ofast")
#include <cstdio>

using namespace std;

typedef long long ll;

const int maxn=200000;
const ll linf=0x7fffffffffffffff;

ll min(ll a, ll b) {
  return a<b ? a : b;
}

ll max(ll a, ll b) {
  return a>b ? a : b;
}

class Hash {
public:
  static const int m=1949111;
  ll key[m];
  int val[m];

  void set(ll k, int v) {
    int p=(k%m+m)%m;
    for (; key[p]; p=(p+1)%m) {
      if (key[p]==k) {
	val[p] = v;
	return;
      }
    }
    key[p] = k, val[p] = v;
  }

  int get(ll k, int def) {
    int p=(k%m+m)%m;
    for (; key[p]; p=(p+1)%m) {
      if (key[p]==k) {
	return val[p];
      }
    }
    return def;
  }
};

class SegmentTree {
public:
  ll a[4*maxn+1], mark[4*maxn+1];

  void markDown(int o, int l, int r) {
    if (mark[o]) {
      if (l!=r) {
	mark[o*2] += mark[o], mark[o*2+1] += mark[o];
      }
      a[o] += mark[o];
      mark[o] = 0;
    }
  }

  void add(int o, int l, int r, int tl, int tr, ll tv) {
    markDown(o, l, r);
    if (l==tl && r==tr) {
      mark[o] += tv;
      markDown(o, l, r);
    } else {
      int mid=(l+r)/2;
      if (tl<=mid && tr>=l) {
	add(o*2, l, mid, max(tl, l),  min(tr, mid), tv);
      }
      if (tl<=r && tr>mid) {
	add(o*2+1, mid+1, r, max(tl, mid+1), min(tr, r), tv);
      }
      markDown(o*2, l, mid);
      markDown(o*2+1, mid+1, r);
      a[o] = min(a[o*2], a[o*2+1]);
    }
  }

  ll getMin(int o, int l, int r, int tl, int tr) {
    markDown(o, l, r);
    if (l==tl && r==tr) {
      return a[o];
    } else {
      int mid=(l+r)/2;
      ll ret=linf;
      if (tl<=mid && tr>=l) {
	ret = min(ret, getMin(o*2, l, mid, max(tl, l), min(tr, mid)));
      }
      if (tl<=r && tr>mid) {
	ret = min(ret, getMin(o*2+1, mid+1, r, max(tl, mid+1), min(tr, r)));
      }
      return ret;
    }
  }
};

int getLower(SegmentTree &a, int n, int l, int r, int k) {
  int ans=l;
  for (int x=l, y=r, mid; x<=y; ) {
    mid=(x+y)/2;
    if (a.getMin(1, 1, n, mid, r)<=k) {
      ans = mid;
      x = mid+1;
    } else {
      y = mid-1;
    }
  }
  return ans;
}

int main() {
  freopen("sequence.in", "r", stdin);
  freopen("sequence.out", "w", stdout);

  static ll a[maxn+1];
  int n, k, d;
  scanf("%d %d %d", &n, &k, &d);
  for (int i=1; i<=n; i++) {
    scanf("%lld", a+i);
    a[i] += linf/2;
  }

  if (d==0) {
    int ansr=1, ansl=1;
    for (int h=1, t=1; t<=n; t++) {
      if (a[h]==a[t]) {
	if (ansr-ansl<t-h) {
	  ansl = h, ansr = t;
	}
      } else {
	h = t;
      }
    }
    printf("%d %d", ansl, ansr);
    return 0;
  }

  static bool seg[maxn+1];
  for (int h=1, t=1; h<=n && t<=n; h=t) {
    for (; t<=n && a[t]%d==a[h]%d; t++);
    seg[t-1] = true;
  }

  static Hash hash;
  static int ind[maxn+1];
  for (int i=n; i>0; i--) {
    ind[i] = hash.get(a[i], n+1);
    hash.set(a[i], i);
  }

  static SegmentTree f;
  static ll mins[maxn+1][2], maxs[maxn+1][2];
  int ansl=n, ansr=n;
  for (int i=n, p, q, j; i>0; i--) {
    if (seg[i]) {
      j = i;
      p = q = 1;
      mins[1][0] = maxs[1][0] = i, mins[1][1] = maxs[1][1] = a[i]/d;
      mins[0][0] = maxs[0][0] = i+1;
    } else {
      for (; p && a[i]/d<mins[p][1]; p--) {
	f.add(1, 1, n, mins[p][0], mins[p-1][0]-1, mins[p][1]);
      }
      f.add(1, 1, n, i, mins[p][0]-1, -a[i]/d);
      mins[++p][0] = i;
      mins[p][1] = a[i]/d;

      for (; q && a[i]/d>maxs[q][1]; q--) {
	f.add(1, 1, n, maxs[q][0], maxs[q-1][0]-1, -maxs[q][1]);
      }
      f.add(1, 1, n, i, maxs[q][0]-1, a[i]/d);
      maxs[++q][0] = i;
      maxs[q][1] = a[i]/d;

      f.add(1, 1, n, i+1, j, -1);

      int t=getLower(f, n, i, min(j, ind[i]-1), k);
      if (t-i>=ansr-ansl) {
	ansl = i, ansr = t;
      }
    }
  }

  printf("%d %d", ansl, ansr);

  fclose(stdin);
  fclose(stdout);
  return 0;
}
